home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part1 / 9603 < prev    next >
Encoding:
Internet Message Format  |  1996-08-05  |  5.4 KB

  1. Path: newshost.cyberramp.net!news
  2. From: sinan@cyberramp.net (John Noland)
  3. Newsgroups: comp.lang.misc,comp.lang.c,comp.lang.pl1
  4. Subject: Re: GOTO controversy
  5. Date: 12 Mar 1996 00:32:31 GMT
  6. Organization: Prose Software
  7. Message-ID: <4i2gmv$ect@newshost.cyberramp.net>
  8. References: <rcshlds.1.000A6705@mailserv.mta.ca> <Dn8pJ8.nqs@emi.net> <4grt4e$8fg@goanna.cs.rmit.EDU.AU> <4hl8mt$4po@newshost.cyberramp.net> <DnwCxp.84C@clw.cs.man.ac.uk>
  9. NNTP-Posting-Host: ramp1-12.cyberramp.net
  10. X-Newsreader: WinVN 0.99.5
  11.  
  12. In article <DnwCxp.84C@clw.cs.man.ac.uk>, chl@clw.cs.man.ac.uk says...
  13. >
  14. >In <4hl8mt$4po@newshost.cyberramp.net> sinan@cyberramp.net (John Noland) writes:
  15. >
  16. >>>Robert C Shields (rcshlds@mailserv.mta.ca) wrote:
  17. >
  18. >>The above is NOT an example of a good use for the goto statement. 
  19. >
  20. >Well that is what I thougut when I first saw the example, and I was about to
  21. >dash off an article like you have done. But then I looked again and saw
  22. >*exactly* what it was doing.
  23. >
  24. >So if you believe there is a better way, please can we see it?
  25. >
  26. I saw *exactly* what it was doing. 
  27.  
  28. I only have one problem with this example. It looks to me like he's trying to avoid
  29. duplicate code by using goto's. Yet, it seems to me that in the spot where he says:
  30.  
  31. /* Do some stuff here */
  32. return TRUE;  /* We did okay */
  33.  
  34. really looks like this:
  35.  
  36. /* Do some stuff here */
  37. NOTE>/* including this? */
  38. NOTE>   free(ptr);
  39. NOTE>   DosCloseMutexSem(hmtx);
  40. NOTE>   DosCloseEventSem(hev3);
  41. NOTE>   DosCloseEventSem(hev2);
  42. NOTE>   DosCloseEventSem(hev1);
  43. return TRUE; /* We did okay */
  44.  
  45. so the obvious change I would make is this:
  46.  
  47. HEV    hev1, hev2, hev3;     /* Event semaphores */
  48. HMTX   hmtx;                 /* Mutex semaphore  */ 
  49. void  *ptr;              
  50. int    retval;   /* I'm assuming he's returning an int */
  51.  
  52. /* There should be explicit initialization of all locals here */
  53.  
  54. retval = TRUE;
  55.  
  56. if (!DosCreateEventSem(0, &hev1, 0, FALSE))
  57.     retval = FALSE;
  58.     goto hev1_failed
  59.  
  60. if (!DosCreateEventSem(0, &hev2, 0, FALSE))
  61.     retval = FALSE;
  62.     goto hev2_failed;
  63.  
  64. if (!DosCreateEventSem(0, &hev3, 0, FALSE))
  65.     retval = FALSE;
  66.     goto hev3_failed;
  67.  
  68. if (!DosCreateMutexSem(0, &hmtx, 0, FALSE))
  69.     retval = FALSE;
  70.     goto hmtx_failed;
  71.  
  72. if ((ptr = malloc(SOME_SIZE)) == NULL)
  73.     retval = FALSE;
  74.     goto malloc_failed;
  75.  
  76. /* Do some stuff here */
  77. free(ptr);
  78.  
  79. malloc_failed:
  80.    DosCloseMutexSem(hmtx);
  81. hmtx_failed:
  82.    DosCloseEventSem(hev3);
  83. hev3_failed:
  84.    DosCloseEventSem(hev2);
  85. hev2_failed:
  86.    DosCloseEventSem(hev1);
  87. hev1_failed:
  88.    return retval;
  89.  
  90.  
  91. To code a proper alternative to the goto's, I would really require some more 
  92. information. I'm not familiar w/ this particular semaphore implementation, 
  93. so I have to make some assumptions. I assume HEV and HMTX are structures 
  94. that contain something similar to the UNIX implementation, semaphore value 
  95. (semval), the process id of the last process to use the semphore(sempid), 
  96. etc... In the implementations I've seen (and I'm not terribly knowledgeable 
  97. about IPC mechanisms in general), there is a function called semget(). I don't 
  98. know much about this, but I do know it returns a semaphore ID. I can't tell 
  99. if that's what DosCreateXXXXSem() is doing or not. The original author treats 
  100. it as a boolean. Something like the following would work to eliminate the goto's, 
  101. but, it would be difficult to prove this method's superiority in this instance.
  102.  
  103. typedef struct {
  104.     int hev_return;
  105.     HEV hev_struct;
  106. } HEV_SEM;
  107.  
  108. typedef struct {
  109.     int hmtx_return; 
  110.     HMTX hmtx_struct;
  111. } HMTX_SEM;
  112.  
  113. int alloc_fn_resources(HEV_SEM *hev1, HEV_SEM *hev2, HEV_SEM *hev3, HMTX_SEM *hmtx, void *ptr);
  114. void free_fn_resources(HEV_SEM *hev1, HEV_SEM *hev2, HEV_SEM *hev3, HMTX_SEM *hmtx, void *ptr);
  115.  
  116. int some_function(void) {
  117.  
  118. int    retval;
  119. HEV_SEM    hev1, hev2, hev3;     /* Event semaphores */
  120. HMTX_SEM   hmtx;                 /* Mutex semaphore  */ 
  121. void  *ptr;              
  122.     
  123.     retval = TRUE;
  124.     memset((HEV_SEM *)&hev1, 0, sizeof (HEV_SEM));
  125.     memset((HEV_SEM *)&hev2, 0, sizeof (HEV_SEM));
  126.     memset((HEV_SEM *)&hev3, 0, sizeof (HEV_SEM));
  127.     memset((HMTX_SEM *)&hmtx, 0, sizeof (HMTX_SEM));
  128.     
  129.     if (!alloc_fn_resources(&hev1, &hev2, &hev3, &hmtx, ptr)) {
  130.     free_fn_resources(&hev1, &hev2, &hev3, &hmtx, ptr);
  131.         return FALSE;
  132.     }
  133.     /* Do some stuff here */
  134.     free_fn_resources(&hev1, &hev2, &hev3, &hmtx, ptr);
  135.     return TRUE;
  136. }
  137.  
  138. int alloc_fn_resources(HEV_SEM *hev1, HEV_SEM *hev2, HEV_SEM *hev3, HMTX_SEM *hmtx, void *ptr) {
  139.  
  140.     if ((hev1->hev_return = DosCreateEventSem(0, &hev1->hev_struct, 0, FALSE)) == 0)
  141.         return FALSE;
  142.     if ((hev2->hev_return = DosCreateEventSem(0, &hev2->hev_struct, 0, FALSE)) == 0)
  143.     return FALSE;
  144.     if ((hev3->hev_return = DosCreateEventSem(0, &hev3->hev_struct, 0, FALSE)) == 0)
  145.         return FALSE;
  146.     if ((hmtx->hmtx_return = DosCreateMutexSem(0, &hmtx->hev_struct, 0, FALSE)) == 0)
  147.         return FALSE;
  148.     if ((ptr = malloc(SOME_SIZE)) == NULL)
  149.     return FALSE;
  150.     return TRUE;
  151. }
  152.  
  153. void free_fn_resources(HEV_SEM *hev1, HEV_SEM *hev2, HEV_SEM *hev3, HMTX_SEM *hmtx, void *ptr);
  154.  
  155. if (ptr != NULL)
  156.     free(ptr);
  157. if (hmtx->hmtx_return != 0)
  158.     DosCloseMutexSem(hmtx->hmtx_struct);
  159. if (hev1->hev_return != 0)
  160.     DosCloseEventSem(hev3->hev_struct);
  161. if (hev2->hev_return != 0)
  162.     DosCloseEventSem(hev2->hev_struct);
  163. if (hev3->hev_return != 0)
  164.     DosCloseEventSem(hev1->hev_struct);
  165.  
  166. }
  167.  
  168. If I made any mistakes here, I apologize. This code is off the top of my head. 
  169.  
  170. -John 
  171.  
  172.